#pragma once

#include <iostream>
#include <string>
#include <vector>
#include <regex>

#include "Request.hpp"
#include "Util.hpp"
#include "Buffer.hpp"

enum HttpRecvStatus
{
    RECV_HTTP_ERROR,
    RECV_HTTP_LINE,
    RECV_HTTP_HEAD,
    RECV_HTTP_BODY,
    RECV_HTTP_OVER
};

static const size_t MAX_LINE = 8192; // 8KB
class HttpContext
{
private:
    int _resp_status;            // 响应状态码
    HttpRecvStatus _recv_status; // 接收以及解析的阶段状态
    HttpRequest _request;        // 已经解析得到的请求信息

private:
    // 接收请求首行
    bool RecvHttpLine(Buffer *buf)
    {
        // 获取一行数据
        std::string line = buf->GetLineAndMove();
        // 缓冲区数据不足一行
        if (line.size() == 0)
        {
            // 都大于8KB了，还没有一个换行符，那么就是有问题的
            if (buf->ReadAbleSize() > MAX_LINE)
            {
                _recv_status = RECV_HTTP_ERROR;
                _resp_status = 414; // URI TOO LONG
                return false;
            }
            // 等待新数据的到来
            return true;
        }
        // 大于8KB了,那么就是有问题的
        if (buf->ReadAbleSize() > MAX_LINE)
        {
            _recv_status = RECV_HTTP_ERROR;
            _resp_status = 414; // URI TOO LONG
            return false;
        }
        return parseHttpLine(line);
    }
    bool parseHttpLine(const std::string &line)
    {
        //构建正则表达式
        std::regex e("(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\?(.*))? (HTTP/1\\.[01])(?:\n|\r\n)?");
        
        //解析请求首行
        std::smatch matches;
        bool ret = std::regex_match(line, matches, e);
        if (ret == false)
        {
            _recv_status = RECV_HTTP_ERROR;
            _resp_status = 400; //BAD REQUEST
            return false;
        }
        _request._method = matches[1];
        _request._path = Util::UrlDeCode(matches[2], false);
        _request._version = matches[4];

        //查询字符串的处理
        std::vector<std::string> query_string_array;
        std::string query_string = matches[3];
        //分割&
        Util::Split(query_string, "&", &query_string_array);
        for(auto &str : query_string_array)
        {
            size_t pos = str.find("=");
            if(pos == std::string::npos)
            {
                _recv_status = RECV_HTTP_ERROR;
                _resp_status = 400; //BAD REQUEST
                return false;
            }
            std::string key = Util::UrlDeCode(str.substr(0, pos), true);
            std::string val = Util::UrlDeCode(str.substr(pos + 1), true);
            _request.SetParam(key, val);
        }
        return true;
    }
    bool RecvHttpHead(Buffer *buf)
    {
        
    }
    bool ParseHttpHead();
    bool RecvHttpBody();

public:
    HttpContext();
    // 获取响应状态码
    int GetRespStatus();
    // 获取请求解析的阶段状态
    HttpRecvStatus RecvStatus();
    // 获取解析后的请求
    HttpRequest &Request();

    // 接收并解析Http请求
    void RecvHttpRequest();
};
